package com.bajiao.common.exception;

import com.bajiao.common.api.vo.RestResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.connection.PoolException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;

import static com.bajiao.common.api.vo.RestResult.fail;

/**
 * @Description: 基于API异常处理器
 * @Author: FanJq
 * @Date: 2024-10-10
 * @Version: V1.0
 */
@RestControllerAdvice
@Slf4j
public class BaJBootExceptionHandler {

	@Autowired
	private MessageSource messageSource;

	/**
	 * 处理自定义异常
	 */
	@ExceptionHandler(BaJBootException.class)
	public RestResult handleRRException(BaJBootException e){
		return RestResult.fail(e.getMessage());

	}

	@ExceptionHandler(NoHandlerFoundException.class)
	public RestResult handlerNoFoundException(Exception e) {
		log.error(e.getMessage(), e);
		return RestResult.fail("路径不存在，请检查路径是否正确");
	}

	@ExceptionHandler(DuplicateKeyException.class)
	public RestResult handleDuplicateKeyException(DuplicateKeyException e){
		log.error(e.getMessage(), e);
		return RestResult.fail("数据库中已存在该记录");
	}

	@ExceptionHandler(Exception.class)
	public RestResult handleException(Exception e){
		log.error(e.getMessage(), e);
		return RestResult.fail("系统开了小差~");
	}

	/**
     * 处理请求方式错误异常
	 */
	@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
	public RestResult HttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e){
		StringBuffer sb = new StringBuffer();
		sb.append("不支持");
		sb.append(e.getMethod());
		sb.append("请求方法，");
		sb.append("支持以下");
		String [] methods = e.getSupportedMethods();
		if(methods!=null){
			for(String str:methods){
				sb.append(str);
				sb.append("、");
			}
		}
		log.error(sb.toString(), e);
		return RestResult.fail(sb.toString());
	}

	/**
     * 处理请求数据类型错误异常
	 */
	@ExceptionHandler(HttpMediaTypeNotSupportedException.class)
	public RestResult HttpMediaTypeNotSupportedException(HttpMediaTypeNotSupportedException e){

		log.error(e.getMessage(), e);
		return RestResult.fail("请求数据类型有误!");
	}

	 /**
	  * spring默认上传大小100MB 超出大小捕获异常MaxUploadSizeExceededException
	  */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public RestResult handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
    	log.error(e.getMessage(), e);
    	return RestResult.fail("文件大小超出10MB限制，请压缩或降低文件质量! ");
    }

    @ExceptionHandler(DataIntegrityViolationException.class)
    public RestResult handleDataIntegrityViolationException(DataIntegrityViolationException e) {
    	log.error(e.getMessage(), e);
        return RestResult.fail("字段太长");
    }

    @ExceptionHandler(PoolException.class)
    public RestResult handlePoolException(PoolException e) {
    	log.error(e.getMessage(), e);
		return RestResult.fail("Redis 连接异常!");
    }

	/**
	 * 处理接口签名异常
	 */
	@ExceptionHandler(DataHandleException.class)
	public RestResult handleDataException(DataHandleException e){
//		log.error(e.getMessage(), e);
		return new RestResult(e.getCode(),e.getMessage(),null);
	}

	/**
	 * 处理接口参数验证异常
	 */
	@ExceptionHandler(MissingServletRequestParameterException.class)
	public RestResult handleParameterException(MissingServletRequestParameterException e){
		return RestResult.fail("缺少参数，" + e.getParameterName() + "不存在");
	}

	/**
	 * javax.validation校验异常
	 * @param req
	 * @param e
	 * @return
	 */
	@ExceptionHandler(value = MethodArgumentNotValidException.class)
	public RestResult<?> validExceptionHandler(HttpServletRequest req, MethodArgumentNotValidException e){
		String[] str = e.getBindingResult().getAllErrors().get(0).getCodes()[1].split("\\.");
		StringBuffer msg = new StringBuffer("");
		msg.append(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
		return RestResult.fail(msg.toString());
	}

	/**
	 * javax.validation校验异常
	 * @param ex
	 * @return
	 */
	@ExceptionHandler(BindException.class)
	public RestResult processErrors(BindException ex) {
		String message = ex.getAllErrors().get(0).getDefaultMessage();
		return RestResult.fail(message);
	}


	@ExceptionHandler(ConstraintViolationException.class)
	public RestResult handlerConstraintViolationException(ConstraintViolationException exception) {
		String message = exception.getConstraintViolations().iterator().next().getMessage();
		return RestResult.fail(message);
	}
}
